package cn.com.shopec.erp.product.service.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.taobao.api.internal.util.StringUtils;

import cn.com.shopec.erp.common.constant.ProductSCMConstant;
import cn.com.shopec.erp.common.page.PageFinder;
import cn.com.shopec.erp.common.page.PageQuery;
import cn.com.shopec.erp.common.utils.DateUtil;
import cn.com.shopec.erp.common.utils.LogicUtil;
import cn.com.shopec.erp.product.commo.DefectiveVoConvertor;
import cn.com.shopec.erp.product.dao.IDefectiveDao;
import cn.com.shopec.erp.product.dao.IProductStockDao;
import cn.com.shopec.erp.product.entity.Defective;
import cn.com.shopec.erp.product.entity.ProductStock;
import cn.com.shopec.erp.product.service.IDefectiveService;
import cn.com.shopec.erp.product.vo.DefectiveVo;
import cn.com.shopec.erp.purchase.entity.StockPurchase;
import cn.com.shopec.erp.purchase.service.IStockPurchaseService;
import cn.com.shopec.erp.stock.commo.ObjectUtil;
import cn.com.shopec.erp.system.common.UserUtils;

/**
 * @ClassName: IProdDefectiveImpl
 * @Description: 次品的Service层的接口实现
 * @author: LiangShunWang
 * @date: 2016-11-21 下午16:40:13
 */
@Service
public class DefectiveServiceImpl implements IDefectiveService {

	@Resource
	private IDefectiveDao defectiveDao;

	@Resource
	private DefectiveVoConvertor defectiveVoConvertor;

	@Resource
	private IProductStockDao productStockDao;

	@Resource
	IStockPurchaseService stockPurchaseService;

	/**
	 * 
	 * @Title: getPagedBrandList
	 * @Description: 分页查询次品信息
	 * @param brandVo
	 * @param pageQuery
	 * @return
	 * @throws @author:
	 *             LiangShunWang
	 * @date: 2016-11-21下午16:52:05
	 */
	@Override
	public PageFinder<DefectiveVo> getPagedBrandList(DefectiveVo defectiveVo, PageQuery pageQuery) throws Exception {
		DetachedCriteria dc = getDetachedCriteria(defectiveVo);
		dc.addOrder(Order.desc("createTime"));
		PageFinder<Defective> pagedBrandList = this.defectiveDao.pagedByCriteria(dc, pageQuery.getPage(),
				pageQuery.getPageSize());
		return this.defectiveVoConvertor.convert2PagedDefectiveVos(pagedBrandList);
	}

	/**
	 * 
	 * @Title: getPagedBrandList
	 * @Description: 分页查询历史次品信息
	 * @param brandVo
	 * @param pageQuery
	 * @return
	 * @throws @author:
	 *             LiangShunWang
	 * @date: 2016-11-21下午16:52:05
	 */
	@Override
	public PageFinder<DefectiveVo> getPagedBrandHistoryList(DefectiveVo defectiveVo, PageQuery pageQuery)
			throws Exception {
		DetachedCriteria dc = getDetachedCriteria(defectiveVo);
		dc.add(Restrictions.or(Restrictions.eq("storageState", ProductSCMConstant.STORAGE_STATE_ADUITED),
				Restrictions.eq("storageState", ProductSCMConstant.STORAGE_STATE_STORAGE)));
		dc.add(Restrictions.isNotNull("changedQualifiedQuantity"));
		dc.add(Restrictions.isNotNull("changedDefectiveQuantity"));
		dc.addOrder(Order.desc("whNo"));
		dc.addOrder(Order.desc("prodNo"));
		dc.addOrder(Order.desc("supCode"));
		dc.addOrder(Order.desc("aduitTime"));
		PageFinder<Defective> pagedBrandList = this.defectiveDao.pagedByCriteria(dc, pageQuery.getPage(),
				pageQuery.getPageSize());
		return this.defectiveVoConvertor.convert2PagedDefectiveVos(pagedBrandList);
	}

	DetachedCriteria getDetachedCriteria(DefectiveVo defectiveVo) {
		DetachedCriteria dc = this.defectiveDao.createCriteria();

		if (defectiveVo != null) {
			// 商品编码
			if (LogicUtil.isNotNullAndEmpty(defectiveVo.getId())) {
				dc.add(Restrictions.like("id", "%" + defectiveVo.getId().trim() + "%"));
			}
			// 商品名称
			if (LogicUtil.isNotNullAndEmpty(defectiveVo.getCommoName())) {
				dc.add(Restrictions.like("commoName", "%" + defectiveVo.getCommoName().trim() + "%"));
			}
			// 仓库名称
			if (LogicUtil.isNotNullAndEmpty(defectiveVo.getWhName())) {
				dc.add(Restrictions.like("whName", "%" + defectiveVo.getWhName().trim() + "%"));
			}
			// 处理方式
			if ((defectiveVo.getDealWith() != null) && (defectiveVo.getDealWith().intValue() != -1)) {
				dc.add(Restrictions.eq("dealWith", defectiveVo.getDealWith()));
			}
			// 供应商编号
			if (LogicUtil.isNotNullAndEmpty(defectiveVo.getSupCode())) {
				dc.add(Restrictions.eq("supCode", defectiveVo.getSupCode()));
			}
			// 审核状态
			if ((defectiveVo.getStorageState() != null) && (defectiveVo.getStorageState().intValue() != -1)) {
				dc.add(Restrictions.eq("storageState", defectiveVo.getStorageState()));
			}
		}
		return dc;
	}

	/**
	 * 
	 * @Title: addDefective
	 * @Description: 增加次品
	 * @param defectiveVo
	 * @return
	 * @throws @author:
	 *             LiangShunWang
	 * @date: 2016-11-22下午11:52:05
	 */
	@Override
	@Transactional
	public void addDefective(List<Defective> defectiveVo) throws Exception {
		String id = null;
		if (defectiveVo != null) {
			for (Defective defective : defectiveVo) {
				if (defective.getId() != null) {
					defective.setId(id);
				}
				defective.setCreateTime(DateUtil.formatTimesTampDate(new Date()));
				if (defective.getStorageState() == null) {
					defective.setStorageState(ProductSCMConstant.STORAGE_STATE_UNADUIT);
				}
				if (defective.getDealWith() == null) {
					defective.setDealWith(ProductSCMConstant.StorageState_DEFECT);
					defective.setDealwithMan(UserUtils.getLoginUserName());
					defective.setDealwithTime(DateUtil.formatTimesTampDate(new Date()));
				}
				defective.setStorageMan(UserUtils.getLoginUserName());
				defectiveDao.save(defective);
			}
		}
	}

	@Override
	@Transactional
	public boolean updateDefective(DefectiveVo defectiveVo) throws Exception {

		if (defectiveVo != null && !StringUtils.isEmpty(defectiveVo.getId())) {
			Defective defective = this.defectiveDao.getById(defectiveVo.getId());
			if (defective != null && defective.getStorageState() != null
					&& defective.getStorageState().intValue() == ProductSCMConstant.STORAGE_STATE_UNADUIT) {
				defective.setProdNo(defectiveVo.getProdNo());
				defective.setCommoNo(defectiveVo.getCommoNo());
				defective.setCommoName(defectiveVo.getCommoName());
				defective.setDefectiveNumber(defectiveVo.getDefectiveNumber());
				defective.setDefectiveReason(defectiveVo.getDefectiveReason());
				defective.setDealWith(defectiveVo.getDealWith());
				defective.setWhNo(defectiveVo.getWhNo());
				defective.setWhName(defectiveVo.getWhName());
				defective.setPoNo(defectiveVo.getPoNo());
				defective.setSupCode(defectiveVo.getSupCode());
				defective.setSupName(defectiveVo.getSupName());
				defective.setDescription(defectiveVo.getDescription());
				defective.setProdBarCode(defectiveVo.getProdBarCode());
				defective.setSpecName(defectiveVo.getSpecName());
				this.defectiveDao.update(defective);
				return true;
			}
		}
		return false;
	}

	@Override
	@Transactional
	public void delDefective(String id) throws Exception {
		if (LogicUtil.isNotNullAndEmpty(id)) {
			Defective defective = this.defectiveDao.get("id", id);
			if (LogicUtil.isNotNull(defective)) {
				// defective.setDeleteFlag(SZSCMConstant.DELETE_FLAG_YES);
				// this.defectiveDao.update(defective);
				this.defectiveDao.removeById(defective.getId());
			}
		}

	}

	@Override
	public DefectiveVo getDefective(String defectiveId) throws Exception {
		return this.defectiveVoConvertor.convert2DefectiveVo(this.defectiveDao.getById(defectiveId));

	}

	@Override
	@Transactional
	public boolean aduitDefective(String defectiveId) throws Exception {
		Defective defective = this.defectiveDao.getById(defectiveId);
		if (defective != null) {
			ProductStock productStock = changeProductQuantity(defective);
			if (productStock != null && changeStockPurchaseQuantity(defective)) {
				defective.setStorageState(ProductSCMConstant.STORAGE_STATE_ADUITED);
				defective.setCreateTime(DateUtil.formatTimesTampDate(new Date()));
				defective.setStorageMan(UserUtils.getLoginUserName());
				defective.setDealwithMan(UserUtils.getLoginUserName());
				defective.setDealwithTime(DateUtil.formatTimesTampDate(new Date()));
				defective.setChangedDefectiveQuantity(productStock.getDefectiveQuantity().toString());
				defective.setChangedQualifiedQuantity(productStock.getQualifiedQuantity().toString());
				this.defectiveDao.update(defective);
				return true;
			}
		}
		return false;
	}

	/**
	 * 修改库存
	 * 
	 * @param defective
	 * @return
	 * @throws Exception
	 */
	@Transactional
	private ProductStock changeProductQuantity(Defective defective) throws Exception {
		int changeQuantity = Integer.valueOf(defective.getDefectiveNumber());
		ProductStock productStock = new ProductStock();
		productStock.setProdNo(defective.getProdNo());
		productStock.setWhNo(defective.getWhNo());
		productStock.setSupNo(defective.getSupCode());
		productStock.setCommoNo(defective.getCommoNo());
		ProductStock productStockFromDB = productStockDao.findUniqueProduct(productStock);

		if (changeQuantity > 0 && productStockFromDB != null) {
			long qualifiedQuantity = productStockFromDB.getQualifiedQuantity();
			long defectiveQuantity = productStockFromDB.getDefectiveQuantity();
			qualifiedQuantity -= (long) changeQuantity;
			defectiveQuantity += (long) changeQuantity;
			if (qualifiedQuantity >= 0 && qualifiedQuantity <= productStockFromDB.getQualifiedQuantity()
					&& defectiveQuantity > productStockFromDB.getDefectiveQuantity()) {
				productStockFromDB.setQualifiedQuantity(qualifiedQuantity);
				productStockFromDB.setDefectiveQuantity(defectiveQuantity);
				productStockDao.update(productStockFromDB);
				return productStockFromDB;
			}
		}
		return null;
	}

	/**
	 * 修改采购单库存关系表数量
	 * 
	 * @param defective
	 * @return
	 * @throws Exception
	 */
	@Transactional
	private boolean changeStockPurchaseQuantity(Defective defective) throws Exception {
		StockPurchase stockPurchase = new StockPurchase();
		stockPurchase.setPoNo(defective.getPoNo());
		stockPurchase.setProdNo(defective.getProdNo());
		stockPurchase.setWhNo(defective.getWhNo());
		stockPurchase.setYieldAmountNumner(-ObjectUtil.toLong(defective.getDefectiveNumber()));
		stockPurchase.setDefectiveAmountNumber(ObjectUtil.toLong(defective.getDefectiveNumber()));
		return stockPurchaseService.changeQuantity(stockPurchase);
	}
}